// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie.savefile;

import java.io.IOException;
import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import zombie.characters.IsoPlayer;
import zombie.core.logger.ExceptionLogger;
import zombie.core.network.ByteBufferWriter;
import zombie.core.raknet.UdpConnection;
import zombie.core.utils.UpdateLimit;
import zombie.debug.DebugLog;
import zombie.iso.IsoCell;
import zombie.iso.IsoChunkMap;
import zombie.iso.IsoWorld;
import zombie.network.GameClient;
import zombie.network.PacketTypes;

public final class ClientPlayerDB {
    private static ClientPlayerDB instance = null;
    private static boolean allow = false;
    private ClientPlayerDB.NetworkCharacterProfile networkProfile = null;
    private UpdateLimit saveToDBPeriod4Network = new UpdateLimit(30000L);
    private static ByteBuffer SliceBuffer4NetworkPlayer = ByteBuffer.allocate(65536);
    private boolean forceSavePlayers;
    public boolean canSavePlayers = false;

    public static void setAllow(boolean en) {
        allow = en;
    }

    public static boolean isAllow() {
        return allow;
    }

    public static synchronized ClientPlayerDB getInstance() {
        if (instance == null && allow) {
            instance = new ClientPlayerDB();
        }

        return instance;
    }

    public static boolean isAvailable() {
        return instance != null;
    }

    public void updateMain() {
        this.saveNetworkPlayersToDB();
    }

    public void close() {
        instance = null;
        allow = false;
    }

    private void saveNetworkPlayersToDB() {
        if (this.canSavePlayers && (this.forceSavePlayers || this.saveToDBPeriod4Network.Check())) {
            this.forceSavePlayers = false;

            for (int _int = 0; _int < IsoPlayer.numPlayers; _int++) {
                IsoPlayer isoPlayer = IsoPlayer.players[_int];
                if (isoPlayer != null) {
                    this.clientSendNetworkPlayerInt(isoPlayer);
                }
            }
        }
    }

    public ArrayList<IsoPlayer> getAllNetworkPlayers() {
        ArrayList arrayList = new ArrayList();

        for (int _int = 1; _int < this.networkProfile.playerCount; _int++) {
            byte[] _byte = this.getClientLoadNetworkPlayerData(_int + 1);
            if (_byte != null) {
                ByteBuffer byteBuffer = ByteBuffer.allocate(_byte.length);
                byteBuffer.rewind();
                byteBuffer.put(_byte);
                byteBuffer.rewind();

                try {
                    IsoPlayer isoPlayer = new IsoPlayer(IsoWorld.instance.CurrentCell);
                    isoPlayer.serverPlayerIndex = _int + 1;
                    isoPlayer.load(byteBuffer, this.networkProfile.worldVersion[_int]);
                    if (this.networkProfile.isDead[_int]) {
                        isoPlayer.getBodyDamage().setOverallBodyHealth(0.0F);
                        isoPlayer.setHealth(0.0F);
                    }

                    arrayList.add(isoPlayer);
                } catch (Exception exception) {
                    ExceptionLogger.logException(exception);
                }
            }
        }

        return arrayList;
    }

    public void clientLoadNetworkCharacter(ByteBuffer bb, UdpConnection connection) {
        boolean boolean0 = bb.get() == 1;
        int int0 = bb.getInt();
        if (boolean0) {
            float float0 = bb.getFloat();
            float float1 = bb.getFloat();
            float float2 = bb.getFloat();
            int int1 = bb.getInt();
            boolean boolean1 = bb.get() == 1;
            int int2 = bb.getInt();
            byte[] _byte = new byte[int2];
            bb.get(_byte);
            if (this.networkProfile != null) {
                this.networkProfile.playerCount++;
                switch (this.networkProfile.playerCount) {
                    case 2:
                        this.networkProfile.worldVersion[1] = int1;
                        this.networkProfile.character[1] = _byte;
                        this.networkProfile.x[1] = float0;
                        this.networkProfile.y[1] = float1;
                        this.networkProfile.z[1] = float2;
                        this.networkProfile.isDead[1] = boolean1;
                        break;
                    case 3:
                        this.networkProfile.worldVersion[2] = int1;
                        this.networkProfile.character[2] = _byte;
                        this.networkProfile.x[2] = float0;
                        this.networkProfile.y[2] = float1;
                        this.networkProfile.z[2] = float2;
                        this.networkProfile.isDead[2] = boolean1;
                        break;
                    case 4:
                        this.networkProfile.worldVersion[3] = int1;
                        this.networkProfile.character[3] = _byte;
                        this.networkProfile.x[3] = float0;
                        this.networkProfile.y[3] = float1;
                        this.networkProfile.z[3] = float2;
                        this.networkProfile.isDead[3] = boolean1;
                }
            } else {
                this.networkProfile = new ClientPlayerDB.NetworkCharacterProfile();
                this.networkProfile.playerCount = 1;
                this.networkProfile.username = GameClient.username;
                this.networkProfile.server = GameClient.ip;
                this.networkProfile.character[0] = _byte;
                this.networkProfile.worldVersion[0] = int1;
                this.networkProfile.x[0] = float0;
                this.networkProfile.y[0] = float1;
                this.networkProfile.z[0] = float2;
                this.networkProfile.isDead[0] = boolean1;
            }

            ByteBufferWriter byteBufferWriter = GameClient.connection.startPacket();
            PacketTypes.PacketType.LoadPlayerProfile.doPacket(byteBufferWriter);
            byteBufferWriter.putByte((byte)(int0 + 1));
            PacketTypes.PacketType.LoadPlayerProfile.send(GameClient.connection);
        } else if (this.networkProfile != null) {
            this.networkProfile.isLoaded = true;
        } else {
            this.networkProfile = new ClientPlayerDB.NetworkCharacterProfile();
            this.networkProfile.isLoaded = true;
            this.networkProfile.playerCount = 0;
            this.networkProfile.username = GameClient.username;
            this.networkProfile.server = GameClient.ip;
            this.networkProfile.character[0] = null;
            this.networkProfile.worldVersion[0] = IsoWorld.getWorldVersion();
        }
    }

    private boolean isClientLoadNetworkCharacterCompleted() {
        return this.networkProfile != null && this.networkProfile.isLoaded;
    }

    public void clientSendNetworkPlayerInt(IsoPlayer player) {
        if (GameClient.connection != null) {
            try {
                ByteBufferWriter byteBufferWriter = GameClient.connection.startPacket();
                PacketTypes.PacketType.SendPlayerProfile.doPacket(byteBufferWriter);
                byteBufferWriter.putByte((byte)(player.serverPlayerIndex - 1));
                String string = player.getDescriptor().getForename() + " " + player.getDescriptor().getSurname();
                byteBufferWriter.putUTF(string);
                byteBufferWriter.putFloat(player.x);
                byteBufferWriter.putFloat(player.y);
                byteBufferWriter.putFloat(player.z);
                byteBufferWriter.putByte((byte)(player.isDead() ? 1 : 0));
                SliceBuffer4NetworkPlayer.rewind();
                player.save(SliceBuffer4NetworkPlayer);
                byte[] _byte = new byte[SliceBuffer4NetworkPlayer.position()];
                SliceBuffer4NetworkPlayer.rewind();
                SliceBuffer4NetworkPlayer.get(_byte);
                byteBufferWriter.putInt(IsoWorld.getWorldVersion());
                byteBufferWriter.putInt(SliceBuffer4NetworkPlayer.position());
                byteBufferWriter.bb.put(_byte);
                PacketTypes.PacketType.SendPlayerProfile.send(GameClient.connection);
            } catch (IOException iOException) {
                GameClient.connection.cancelPacket();
                ExceptionLogger.logException(iOException);
            } catch (BufferOverflowException bufferOverflowException) {
                GameClient.connection.cancelPacket();
                int _int = SliceBuffer4NetworkPlayer.capacity();
                if (_int > 2097152) {
                    DebugLog.log("FATAL ERROR: The player " + player.getUsername() + " cannot be saved");
                    ExceptionLogger.logException(bufferOverflowException);
                    return;
                }

                SliceBuffer4NetworkPlayer = ByteBuffer.allocate(_int * 2);
                this.clientSendNetworkPlayerInt(player);
            }
        }
    }

    public boolean isAliveMainNetworkPlayer() {
        return !this.networkProfile.isDead[0];
    }

    public boolean clientLoadNetworkPlayer() {
        if (this.networkProfile != null
            && this.networkProfile.isLoaded
            && this.networkProfile.username.equals(GameClient.username)
            && this.networkProfile.server.equals(GameClient.ip)) {
            return this.networkProfile.playerCount > 0;
        } else if (GameClient.connection == null) {
            return false;
        } else {
            if (this.networkProfile != null) {
                this.networkProfile = null;
            }

            ByteBufferWriter byteBufferWriter = GameClient.connection.startPacket();
            PacketTypes.PacketType.LoadPlayerProfile.doPacket(byteBufferWriter);
            byteBufferWriter.putByte((byte)0);
            PacketTypes.PacketType.LoadPlayerProfile.send(GameClient.connection);
            int _int = 200;

            while (_int-- > 0) {
                if (this.isClientLoadNetworkCharacterCompleted()) {
                    return this.networkProfile.playerCount > 0;
                }

                try {
                    Thread.sleep(50L);
                } catch (InterruptedException interruptedException) {
                    ExceptionLogger.logException(interruptedException);
                }
            }

            return false;
        }
    }

    public byte[] getClientLoadNetworkPlayerData(int _int) {
        if (this.networkProfile != null
            && this.networkProfile.isLoaded
            && this.networkProfile.username.equals(GameClient.username)
            && this.networkProfile.server.equals(GameClient.ip)) {
            switch (_int) {
                case 1:
                case 2:
                case 3:
                case 4:
                    return this.networkProfile.character[_int - 1];
                default:
                    return null;
            }
        } else if (!this.clientLoadNetworkPlayer()) {
            return null;
        } else {
            switch (_int) {
                case 1:
                case 2:
                case 3:
                case 4:
                    return this.networkProfile.character[_int - 1];
                default:
                    return null;
            }
        }
    }

    public boolean loadNetworkPlayer() {
        try {
            byte[] _byte = this.getClientLoadNetworkPlayerData(1);
            if (_byte != null) {
                ByteBuffer byteBuffer = ByteBuffer.allocate(_byte.length);
                byteBuffer.rewind();
                byteBuffer.put(_byte);
                byteBuffer.rewind();
                if (IsoPlayer.getInstance() == null) {
                    IsoPlayer.setInstance(new IsoPlayer(IsoCell.getInstance()));
                    IsoPlayer.players[0] = IsoPlayer.getInstance();
                }

                IsoPlayer.getInstance().serverPlayerIndex = 1;
                IsoPlayer.getInstance().load(byteBuffer, this.networkProfile.worldVersion[0]);
                return true;
            }
        } catch (Exception exception) {
            ExceptionLogger.logException(exception);
        }

        return false;
    }

    public boolean loadNetworkPlayerInfo(int playerIndex) {
        if (this.networkProfile != null
            && this.networkProfile.isLoaded
            && this.networkProfile.username.equals(GameClient.username)
            && this.networkProfile.server.equals(GameClient.ip)
            && playerIndex >= 1
            && playerIndex <= 4
            && playerIndex <= this.networkProfile.playerCount) {
            int int0 = (int)(this.networkProfile.x[playerIndex - 1] / 10.0F) + IsoWorld.saveoffsetx * 30;
            int int1 = (int)(this.networkProfile.y[playerIndex - 1] / 10.0F) + IsoWorld.saveoffsety * 30;
            IsoChunkMap.WorldXA = (int)this.networkProfile.x[playerIndex - 1];
            IsoChunkMap.WorldYA = (int)this.networkProfile.y[playerIndex - 1];
            IsoChunkMap.WorldZA = (int)this.networkProfile.z[playerIndex - 1];
            IsoChunkMap.WorldXA = IsoChunkMap.WorldXA + 300 * IsoWorld.saveoffsetx;
            IsoChunkMap.WorldYA = IsoChunkMap.WorldYA + 300 * IsoWorld.saveoffsety;
            IsoChunkMap.SWorldX[0] = int0;
            IsoChunkMap.SWorldY[0] = int1;
            IsoChunkMap.SWorldX[0] = IsoChunkMap.SWorldX[0] + 30 * IsoWorld.saveoffsetx;
            IsoChunkMap.SWorldY[0] = IsoChunkMap.SWorldY[0] + 30 * IsoWorld.saveoffsety;
            return true;
        } else {
            return false;
        }
    }

    public void forgetPlayer(int serverPlayerIndex) {
        if (this.networkProfile != null && serverPlayerIndex >= 1 && serverPlayerIndex <= 4) {
            this.networkProfile.character[serverPlayerIndex - 1] = null;
            this.networkProfile.isDead[serverPlayerIndex - 1] = true;
        }
    }

    public int getNextServerPlayerIndex() {
        if (this.networkProfile != null
            && this.networkProfile.isLoaded
            && this.networkProfile.username.equals(GameClient.username)
            && this.networkProfile.server.equals(GameClient.ip)) {
            for (int _int = 1; _int < 4; _int++) {
                if (this.networkProfile.character[_int] == null || this.networkProfile.isDead[_int]) {
                    return _int + 1;
                }
            }
        }

        return 2;
    }

    private final class NetworkCharacterProfile {
        boolean isLoaded = false;
        final byte[][] character;
        String username;
        String server;
        int playerCount = 0;
        final int[] worldVersion;
        final float[] x;
        final float[] y;
        final float[] z;
        final boolean[] isDead;

        public NetworkCharacterProfile() {
            this.character = new byte[4][];
            this.worldVersion = new int[4];
            this.x = new float[4];
            this.y = new float[4];
            this.z = new float[4];
            this.isDead = new boolean[4];
        }
    }
}
